export class MySocket {
  constructor(url, options = {}) {
    this.ws = null
    this.url = url
    this.options = options
    console.log('create websocket', url)
  }
  init() {
    this.ws = new WebSocket(this.url)
    console.log('init websocket')
    this.ws.onopen = () => {
      console.log('链接打开：', this.ws.url)
    }
    this.ws.onmessage = (event) => {
      console.log('接收数据：', event.data)
    }
    this.ws.onerror = (error) => {
      console.error('错误：', error)
    }
    this.ws.onclose = (event) => {
      console.log('链接关闭：', event.code)
      this.ws = null
    }
    return this.ws
  }
  connect() {
    console.log('connect websocket')
    if (this.ws) {
      if (this.ws.readyState === WebSocket.OPEN) return
      this.ws.close()
      this.ws.addEventListener('close', () => this.init(), { once: true })
    } else this.init()
  }
  connecting() {
    console.log('connect websocket')
    return new Promise((resolve, reject) => {
      var init = () => {
        try {
          console.log('初始化 websocket')
          this.ws = new WebSocket(this.url)
        } catch (e) {
          reject(e)
        }
        this.ws.onopen = () => {
          console.log('链接打开：', this.ws.url)
          resolve()
        }
        this.ws.onmessage = (event) => {
          console.log('接收数据：', event.data)
        }
        this.ws.onerror = (error) => {
          console.error('错误：', error)
        }
        this.ws.onclose = (event) => {
          console.log('链接关闭：', event.code)
          this.ws = null
        }
        return this.ws
      }
      if (this.ws) {
        if (this.ws.readyState === WebSocket.OPEN) resolve()
        this.ws.close()
        this.ws.addEventListener('close', () => init(), { once: true })
      } else init()
    })
  }
  send(action, params) {
    return new Promise((resolve, reject) => {
      var reqCode = Math.floor(Math.random() * 10000000000000000)
      var get = function (event) {
        var data = JSON.parse(event.data)
        console.log('handle of ', reqCode)
        if (data.info.res == reqCode) {
          resolve(data)
          event.target.removeEventListener('message', get)
        }
      }
      var put = function (event) {
        let packet = { type: action, data: params, info: { req: reqCode } }
        event.send(JSON.stringify(packet))
        event.addEventListener('message', get)
        window.setTimeout(() => {
          event.removeEventListener('message', get)
          reject('overtime')
        }, 3000)
      }
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        put(this.ws)
      } else {
        /*###this.connect();this.ws.addEventListener('open',(e) => put(e.target),{once: true })###*/
        this.connecting().then(() => {
          this.ws.addEventListener('open', (e) => put(e.target), {
            once: true
          })
        })
      }
    })
  }
  close() {
    this.ws.close()
  }
}
export class Socketing {
  constructor(url, options = {}) {
    this.ws = null
    this.url = url
    this.options = options
    console.log('create websocket', url)
  }
  connecting(url = '') {
    return new Promise((resolve, reject) => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        resolve()
      } else {
        if (!this.url) this.url = url
        try {
          this.ws = new WebSocket(this.url)
          console.log('init websocket')
          this.ws.onopen = () => {
            console.log('链接打开：', this.ws.url)
            resolve()
          }
          this.ws.onmessage = (event) => {
            console.log('接收数据：', event.data)
          }
          this.ws.onerror = (error) => {
            console.error('错误：', error)
          }
          this.ws.onclose = (event) => {
            console.log('链接关闭：', event)
            this.ws = null
          }
        } catch (e) {
          reject(e)
        }
      }
    })
  }
  getting(reqCode) {
    return new Promise((resolve, reject) => {
      var get = function (event) {
        var data = JSON.parse(event.data)
        console.log('handle of ', reqCode)
        if (data.info.res == reqCode) {
          resolve(data)
          event.target.removeEventListener('message', get)
        }
      }
      this.ws.addEventListener('message', get)
      window.setTimeout(() => {
        if (this.ws) this.ws.removeEventListener('message', get)
        reject('overtime')
      }, 3000)
    })
  }
  sending(action, params, type = 'query') {
    return new Promise((resolve, reject) => {
      var reqCode = Math.floor(Math.random() * 10000000000000000)
      this.connecting()
        .then(() => {
          let packet = { type: type, data: params, info: { req: reqCode, action: action } }
          this.ws.send(JSON.stringify(packet))
          console.log('发送数据：', packet)
          this.getting(reqCode).then((data) => {
            resolve(data)
          })
        })
        .catch((error) => {
          reject(error)
        })
    })
  }
  closing() {
    return new Promise((resolve) => {
      this.ws.addEventListener('close', (c) => resolve(c.code, c.reason), { once: true })
      this.ws.close()
    })
  }
  ws() {
    return this.ws
  }
  test() {
    this.connecting().then(() => {
      this.ws.send('{"type":0,"data":"Hello ws service!","info":{"action":"test"}}')
    })
  }
}

function socket() {}
//socket.url = 'ws://localhost:3000/users/common'
socket.url = 'ws://localhost:8000'
export function getSocket() {
  if (!socket.instance) socket.instance = new Socketing(socket.url)
  //socket.instance.connecting()
  return socket.instance
}

export function wsending(url = '', params = {}, type = 'query') {
  if (!socket.instance) socket.instance = new Socketing(socket.url)
  return socket.instance.sending(url, params, type)
}
